package com.gitee.wsl.common.chart.sample

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PointF
import com.gitee.wsl.android.ext.math.calcArcEndPointXY
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.listener.click.ArcPosition
import com.gitee.wsl.common.chart.sample.pie.model.PieData
import com.gitee.wsl.common.chart.render.foreground.info.PlotLabel
import com.gitee.wsl.common.chart.model.PlotArcLabelInfo
import com.gitee.wsl.common.chart.render.shape.line.LabelBrokenLine
import com.gitee.wsl.math.Math

import org.xclcharts.common.MathHelper

import timber.log.Timber

abstract class AbstractCirChart( touchCheckAble: com.gitee.wsl.common.ui.api.TouchCheckAble? = null) : XChart(touchCheckAble) {
    //半径
    override var radius = 0.0f

    //标签注释显示位置 [隐藏,Default,Inside,Ouside,Line]
    var labelStyle = ChartEnum.SliceLabelStyle.INSIDE
        set(value) {
            field = value
            when (value) {
                ChartEnum.SliceLabelStyle.INSIDE -> labelPaint.textAlign = Paint.Align.CENTER
                ChartEnum.SliceLabelStyle.OUTSIDE -> {}
                ChartEnum.SliceLabelStyle.HIDE -> {}
                ChartEnum.SliceLabelStyle.BROKENLINE -> {}
            }
        }

    //开放标签画笔让用户设置
    val labelPaint: Paint by lazy {
        Paint(Paint.ANTI_ALIAS_FLAG).apply {
            color = Color.BLACK
            isAntiAlias = true
            textAlign = Paint.Align.CENTER
            textSize = 18f
        }
    }

    //初始偏移角度
    protected var offsetAngle = 0.0f //180;

    /**
     * 设置饼图(pie chart)起始偏移角度
     * @param Angle 偏移角度
     */
    protected var initOffsetAngle = 0.0f
        set(value) {
            field = value
            offsetAngle = value
        }

    //折线标签基类
     var labelLine: LabelBrokenLine? = null

    //同步标签颜色
     val isLabelLineSyncColor = false
     val isLabelPointSyncColor = false
     val isLabelSyncColor = false

    //用于设置标签特性
     val plotLabel: PlotLabel? = null

    override fun calcPlotRange() {
        super.calcPlotRange()
        radius = (plotViewport.width/2f).coerceAtMost((plotViewport.height/2f))
    }

    /**
     * 设置标签显示在扇区的哪个位置(里面，外面，隐藏)
     * @param style 显示位置
     */
   /* @JvmName("setLabelStyle1")
    fun setLabelStyle(style: ChartEnum.SliceLabelStyle) {
        labelStyle = style
    }*/

    protected  fun drawLabelInside(
        canvas: Canvas, text: String, itemAngle: Float,
        cirX: Float, cirY: Float, radius: Float, calcAngle: Float,
        isShowLabel: Boolean
    ): PointF {
        //显示在扇形的中心
        val calcRadius = (radius-radius / 2f)

        //计算百分比标签
        val point = Math.calcArcEndPointXY(cirX, cirY, calcRadius, calcAngle)
        //标识
        if (isShowLabel) {
            //DrawHelper.getInstance().drawRotateText(text, point.x, point.y, itemAngle,
            //												canvas, mPaintLabel);
            plotLabel?.renderLabel(canvas, labelPaint, text, point.x, point.y, itemAngle)
        }
        return PointF(point.x, point.y)
    }

    protected  fun drawLabelOutside(
        canvas: Canvas, text: String, itemAngle: Float,
        cirX: Float, cirY: Float, radius: Float, calcAngle: Float,
        isShowLabel: Boolean
    ): PointF {
        //显示在扇形的外部
        val calcRadius = MathHelper.getInstance().add(radius, radius / 10f)
        //计算百分比标签
        val point = Math.calcArcEndPointXY(cirX, cirY, calcRadius, calcAngle)

        //标识
        if (isShowLabel) {
            //DrawHelper.getInstance().drawRotateText(text, point.x, point.y, itemAngle,
            //													canvas, mPaintLabel);
            plotLabel?.renderLabel(canvas, labelPaint, text, point.x, point.y, itemAngle)
        }
        return PointF(point.x, point.y)
    }

    //折线标签
    protected  fun drawLabelLine(
        canvas: Canvas, cData: PieData,
        cirX: Float, cirY: Float, radius: Float, calcAngle: Float,
        showLabel: Boolean
    ): PointF {
        if (null == labelLine) labelLine = LabelBrokenLine()
        if (isLabelLineSyncColor) labelLine!!.labelLinePaint.color = cData.sliceColor
        if (isLabelPointSyncColor) labelLine!!.pointPaint.color = cData.sliceColor
        return labelLine!!.renderLabelLine(
            cData.label, cData.itemLabelRotateAngle,
            cirX, cirY, radius, calcAngle,
            canvas, labelPaint, showLabel, plotLabel
        )
    }

    /**
     * 绘制标签
     * @param canvas    画布
     * @param cData    PieData类
     * @param info        信息类
     * @param savePosition    是否保存位置
     * @param showLabel    是否显示标签
     * @return 是否成功
     */
    protected  fun drawLabel(
        canvas: Canvas, cData: PieData,
        info: PlotArcLabelInfo,
        savePosition: Boolean,
        showLabel: Boolean
    ): Boolean {
        if (ChartEnum.SliceLabelStyle.HIDE == labelStyle) return true
        val text = cData.label
        if ("" === text || text.isEmpty()) return true
        val cirX = info.x
        val cirY = info.y
        val radius = info.radius
        val offsetAngle = info.offsetAngle
        val calcAngle = (offsetAngle+info.currentAngle / 2f)
        if (calcAngle.compareTo(0.0f) == 0 || calcAngle.compareTo(0.0f) == -1) {
            Timber.d("计算出来的圆心角等于0.")
            return false
        }
        var position: PointF? = null

        //标签颜色与当地扇区颜色同步
        if (isLabelSyncColor) this.labelPaint.color = cData.sliceColor
        val color: Int = labelPaint.color

        //有定制需求
        var labelStyle = labelStyle
        if (cData.isCustLabelStyle) {
            labelStyle = cData.labelStyle
            if (ChartEnum.SliceLabelStyle.INSIDE == labelStyle) labelPaint.textAlign =
                Paint.Align.CENTER
            labelPaint.color = cData.custLabelColor
        }
        position = if (ChartEnum.SliceLabelStyle.INSIDE == labelStyle) {
            //显示在扇形的内部
            drawLabelInside(
                canvas, text, cData.itemLabelRotateAngle,
                cirX, cirY, radius, calcAngle, showLabel
            )
        } else if (ChartEnum.SliceLabelStyle.OUTSIDE == labelStyle) {
            //显示在扇形的外部
            drawLabelOutside(
                canvas, text, cData.itemLabelRotateAngle,
                cirX, cirY, radius, calcAngle, showLabel
            )
        } else if (ChartEnum.SliceLabelStyle.BROKENLINE == labelStyle) {
            //显示在扇形的外部
            //1/4处为起始点
            drawLabelLine(canvas, cData, cirX, cirY, radius, calcAngle, showLabel)
        } else {
            Timber.d("未知的标签处理类型.")
            return false
        }
        labelPaint.color = color
        if (savePosition) info.labelPointF = position //保存标签坐标位置
        return true
    }

    override fun renderBody(canvas: Canvas): Boolean {
        super.renderBody(canvas)

        //计算主图表区范围
        calcPlotRange()
        //画Plot Area背景
        plotViewport.render(canvas)
        //绘制标题
        drawTitle(canvas)
        return true
    }


   /* override fun render(canvas: Canvas) {
        // TODO Auto-generated method stubcalcPlotRange
        if (isScrollEnabled) {
            canvas.save()
            when (plotPanMode) {
                DrawEnum.PanMode.HORIZONTAL -> canvas.translate(translateXY[0], 0f)
                DrawEnum.PanMode.VERTICAL -> canvas.translate(0f, translateXY[1])
                else -> canvas.translate(translateXY[0], translateXY[1])
            }

            //绘制图表
            super.render(canvas)

            //还原
            canvas.restore()
        } else {
            //绘制图表
            super.render(canvas)
        }
    }*/

    /**
     * 图，扇形类的焦点参数
     *
     * @param arc
     * 扇形选中类
     */
    open fun showFocusArc(arc: ArcPosition, selected: Boolean=false) {
        selectHelper.showFocusArc(arc,selected)
    }

}